package dream

import (
	"encoding/json"
	"errors"
	"strconv"
	"time"
)

const LOG_HTTP = -419

const LONG_TIME_FUNC = time.Duration(100) * time.Millisecond

// type IRequestData = *JSONRead
type IRequestData []byte //= *json.Decoder
type IRequestComm = *ClientMeta

/*FishClientMeta 客户端信息
 */
type ClientMeta struct {
	VerCode  int32  //客户端版本
	AppID    string //客户端APPKEY
	DeviceID string ////客户端设备特征码
}

/*Decode 客户端请求数据
 */
func (p IRequestData) Decode(v interface{}) error {
	return json.Unmarshal([]byte(p), v)
}

type sVioHandler struct {
	handler func(IRequest, IResponse)
}

func durationString(d time.Duration) string {
	if d > LONG_TIME_FUNC {
		return "[" + strconv.Itoa(int(d.Nanoseconds()/time.Millisecond.Nanoseconds())) + "ms]"
	}
	return ""
}

func (p *sVioHandler) OnHttpRequest(r IRequest, w IResponse) {
	bT := time.Now()
	p.handler(r, w)
	Logi(LOG_HTTP, r.RemoteAddr, ",", r.URL.Path, durationString(time.Since(bT)))
}

type sClientHandler struct {
	handler func(IRequestData, IRequestComm, IRequest, IResponse)
}

type dataReader struct {
	buf []byte
	pos int
}

func (p *dataReader) Read(b []byte) (int, error) {
	n := 0
	left := len(p.buf) - p.pos
	if len(b) <= left {
		n = len(b)
		copy(b, p.buf[p.pos:])
		p.pos += n
	} else {
		n = left
		copy(b, p.buf[p.pos:])
		p.pos += n
	}
	left = len(p.buf) - p.pos
	if left <= 0 {
		return n, errors.New("EOF")
	}
	return n, nil
}

func (p *sClientHandler) OnHttpRequest(r IRequest, w IResponse) {
	//Logi(LOG_HTTP, r.URL.Path, ":")
	//p.handler(r, w)
	bd := r.Body
	//j := NewJSONRead()
	//json.NewDecoder(bd).Decode(&j.JSONT)
	rdata := make([]byte, r.ContentLength)
	nlen, _ := bd.Read(rdata)
	bd.Close()
	if nlen == 0 {
		Logi(LOG_HTTP, r.RemoteAddr, ",*C,", r.URL.Path)
		return
	}
	rdata = rdata[0:nlen]

	c := &ClientMeta{}

	bT := time.Now()
	p.handler(IRequestData(rdata) /*json.NewDecoder(&dataReader{buf: rdata}) */ /*j*/, c, r, w)
	Logi(LOG_HTTP, r.RemoteAddr, ",C,", r.URL.Path, ",", string(rdata) /*j.JSONT*/, durationString(time.Since(bT)))
}

type sUserHandler struct {
	handler func(int, IRequestData, IRequestComm, IRequest, IResponse)
}

func (p *sUserHandler) OnHttpRequest(r IRequest, w IResponse) {
	bd := r.Body
	//j := NewJSONRead()
	//json.NewDecoder(bd).Decode(&j.JSONT)
	rdata := make([]byte, r.ContentLength)
	nlen, _ := bd.Read(rdata)
	bd.Close()
	if nlen == 0 {
		Logi(LOG_HTTP, r.RemoteAddr, ",*U,", r.URL.Path)
		return
	}
	rdata = rdata[0:nlen]

	fj := NewJSONRead()
	json.NewDecoder(&dataReader{buf: rdata}).Decode(&(fj.JSONT))
	var userID int
	userID = int(fj.Num("userID"))
	if userID == 0 {
		Logi(LOG_HTTP, r.RemoteAddr, ",*U,", r.URL.Path)
		return
	}

	c := &ClientMeta{}

	bT := time.Now()
	p.handler(userID, IRequestData(rdata) /*json.NewDecoder(&dataReader{buf: rdata})*/ /*j*/, c, r, w)
	Logi(LOG_HTTP, r.RemoteAddr, ",U,", userID, ",", r.URL.Path, ",", string(rdata) /*j.JSONT*/, durationString(time.Since(bT)))
}
